/*
 * 文件名：RealStreamCTLHandler.java
 * 版权：亚信联创版权所有
 * 描述：TODO
 * 修改人：yuanze
 * 修改时间：2014年10月31日
 * 修改内容：TODO
 */
package com.ailk.bigdata.etl.realstream.server.protocal.aipr.netty.handler;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ailk.bigdata.etl.common.server.net.NettyUtil;
import com.ailk.bigdata.etl.realstream.server.model.CmdEnum;
import com.ailk.bigdata.etl.realstream.server.model.RealStreamUser;
import com.ailk.bigdata.etl.realstream.server.model.ResponseCodeEnum;
import com.ailk.bigdata.etl.realstream.server.protocal.aipr.service.UserCtlCmdService;
import com.ailk.bigdata.etl.realstream.server.protocal.aipr.service.impl.UserCtlCmdServiceImpl;
import com.ailk.bigdata.etl.realstream.server.tools.RealStreamTool;

/**
 * @description 实时流命令控制Handler
 * @author [yuanze]
 * @version [版本号,2014年10月31日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Sharable
public class RealStreamCTLHandler extends SimpleChannelInboundHandler<String>
{
	private static final Logger logger = LoggerFactory.getLogger(RealStreamCTLHandler.class);

	/**
	 * @see io.netty.channel.ChannelInboundHandlerAdapter#channelActive(io.netty.channel.ChannelHandlerContext)
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception
	{
		// 首次连接发送索要用户名请求
		RealStreamUser user = new RealStreamUser();
		user.setClientIP(NettyUtil.getClientIp(ctx));// 客户端地址信息
		user.setCtx(ctx);
		RealStreamTool.AUTHENTICATION_INFO_CACHE.put(ctx.channel().remoteAddress().toString(), user);
		// ctx.writeAndFlush(String.valueOf(ResponseCodeEnum.ASKUSER.getCode()));
		ctx.writeAndFlush(String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode()));
		logger.info("received remoteAdd [" + ctx.channel().remoteAddress() + "] request.........");
	}

	@Override
	public void channelRead0(ChannelHandlerContext ctx, String cmd) throws Exception
	{
		logger.info("request from [" + ctx.channel().remoteAddress() + "] command [" + cmd + "].........");
		RealStreamUser user = RealStreamTool.AUTHENTICATION_INFO_CACHE.get(ctx.channel().remoteAddress().toString());
		ctx.writeAndFlush(parseCmd(cmd.trim(), user));
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
	{
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
	{
		logger.error("Unexpected exception from downstream.", cause);
		ctx.close();
	}

	/**
	 * 
	 * @description 解析命令
	 * @param cmd
	 * @return
	 */
	private String parseCmd(String cmd, RealStreamUser user)
	{
		String responseCode = "";
		boolean isRightful = false;// 命令是否合法
		logger.debug("cmd[" + cmd + "] method.........................");
		for (CmdEnum cmdEnum : CmdEnum.values())
		{
			logger.debug("cmd[" + cmd + "]pattern[" + cmdEnum.getPattern() + "]" + cmd.matches(cmdEnum.getPattern()));
			if (cmd.matches(cmdEnum.getPattern()))
			{
				try
				{
					logger.debug("cmd[" + cmd + "] method[" + cmdEnum.getMethod() + "]");
					UserCtlCmdService ctlCmdService = new UserCtlCmdServiceImpl();
					Class<?> cmdService = ctlCmdService.getClass();
					Method method = cmdService.getMethod(cmdEnum.getMethod(), String.class, RealStreamUser.class);
					responseCode = String.valueOf(method.invoke(ctlCmdService, cmd, user));
					isRightful = true;
				}
				catch (Exception e)
				{
					logger.error("cmd parse exception", e);
				}
				break;
			}
		}
		if (!isRightful)
		{
			logger.warn("cmd[" + cmd + "] is invalid");
			responseCode = String.valueOf(ResponseCodeEnum.INVALIDCMD.getCode());
		}
		logger.info("responseCode[" + responseCode + "]");
		responseCode = String.valueOf(ResponseCodeEnum.CMDEXECUTESUC.getCode());
		return responseCode;
	}
}
